package com.info.pan.exception;

import com.info.pan.core.exception.HPanBusinessException;
import com.info.pan.core.exception.HPanFrameworkException;
import com.info.pan.core.response.ResponseEnum;
import com.info.pan.core.response.ResultCode;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class WebExceptionHandler {

    @ExceptionHandler(value = HPanBusinessException.class)
    public ResultCode rPanBusinessExceptionHandler(HPanBusinessException e) {
        return ResultCode.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResultCode methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        ObjectError objectError = e.getBindingResult().getAllErrors().stream().findFirst().get();
        return ResultCode.fail(ResponseEnum.ERROR_PARAM.getCode(), objectError.getDefaultMessage());
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public ResultCode constraintDeclarationExceptionHandler(ConstraintViolationException e) {
        ConstraintViolation<?> constraintViolation = e.getConstraintViolations().stream().findFirst().get();
        return ResultCode.fail(ResponseEnum.ERROR_PARAM.getCode(), constraintViolation.getMessage());
    }

    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public ResultCode missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
        return ResultCode.fail(ResponseEnum.ERROR_PARAM);
    }

    @ExceptionHandler(value = IllegalStateException.class)
    public ResultCode illegalStateExceptionHandler(IllegalStateException e) {
        return ResultCode.fail(ResponseEnum.ERROR_PARAM);
    }

    @ExceptionHandler(value = BindException.class)
    public ResultCode bindExceptionHandler(BindException e) {
        FieldError fieldError = e.getBindingResult().getFieldErrors().stream().findFirst().get();
        return ResultCode.fail(ResponseEnum.ERROR_PARAM.getCode(), fieldError.getDefaultMessage());
    }

    @ExceptionHandler(value = HPanFrameworkException.class)
    public ResultCode rPanFrameworkExceptionHandler(HPanFrameworkException e) {
        return ResultCode.fail(ResponseEnum.ERROR.getCode(), e.getMessage());
    }

    @ExceptionHandler(value = RuntimeException.class)
    public ResultCode runtimeExceptionHandler(RuntimeException e) {
        return ResultCode.fail(ResponseEnum.ERROR.getCode(), e.getMessage());
    }

}
